package com.san.base.controller;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.san.base.domain.DictDO;
import com.san.base.domain.Tree;
import com.san.base.service.DictService;
import com.san.base.vo.DictVO;
import com.san.common.annotation.Log;
import com.san.common.utils.Constant;
import com.san.common.utils.PageUtils;
import com.san.common.utils.Query;
import com.san.common.utils.R;

/**
 * 字典表
 */
@Controller
@RequestMapping("/base/dict")
public class DictController extends BaseController {
	
	private static final Logger logger = LoggerFactory.getLogger(DictController.class);

	/**
	 * 本功能地址前缀
	 */
	private static final String PREFIX = "base/dict";

	@Autowired
	private DictService dictService;

	@GetMapping("")
	@Log("访问数据字典")
	@RequiresPermissions("base:dict:view")
	String dict() {
		return PREFIX + "/view";
	}

	@ResponseBody
	@GetMapping("/list")
	@RequiresPermissions("base:dict:view")
	public PageUtils list(@RequestParam Map<String, Object> params) {
		if (null == params.get("parentId") || "".equals(params.get("parentId"))
				|| "-1".equals(params.get("parentId"))) {
			params.put("parentId", new Long(0));
		}

		// 查询列表数据
		Query query = new Query(params);
		List<DictDO> dictList = dictService.list(query);
		int total = dictService.count(query);
		PageUtils pageUtils = new PageUtils(dictList, total);
		return pageUtils;
	}

	/**
	 * 新增数据字典
	 * 
	 * @param model
	 * @param parentId
	 * @return
	 */
	@GetMapping("/add/{id}")
	@Log("访问新增数据字典页面")
	@RequiresPermissions("base:dict:add")
	String add(Model model, @PathVariable("id") Long parentId) {
		if (null == parentId || parentId == -1 || parentId == 0) {
			model.addAttribute("parentId", 0);
			model.addAttribute("parentName", "顶级节点");
		} else {
			DictDO dictDO = dictService.getById(parentId);
			model.addAttribute("parentId", parentId);
			model.addAttribute("parentName", dictDO.getName());
		}

		return PREFIX + "/add";
	}

	/**
	 * 保存数据字典
	 */
	@ResponseBody
	@Log("新增数据字典")
	@PostMapping("/save")
	@RequiresPermissions("base:dict:add")
	public R save(DictVO dict) {
		R r = checkValue(dict);
		if (!R.ok().equals(r)) {
			return r;
		}

		dict.setCreateUserId(getUserId());
		dict.setCreateDate(new Date());

		try {
			if (dictService.save(dict) > 0) {
				return R.ok();
			}
		} catch (Exception e) {
			logger.error("数据字典新增失败",e);
		}

		return R.error();
	}

	@GetMapping("/edit/{id}")
	@Log("数据字典修改页面")
	@RequiresPermissions("base:dict:edit")
	String edit(@PathVariable("id") Long id, Model model) {
		DictDO dict = dictService.getById(id);
		model.addAttribute("dict", dict);
		return PREFIX + "/edit";
	}

	/**
	 * 修改
	 */
	@ResponseBody
	@Log("更新数据字典")
	@RequestMapping("/doEdit")
	@RequiresPermissions("base:dict:edit")
	public R doEdit(DictVO dict) {
		R r = checkValue(dict);
		if (!R.ok().equals(r)) {
			return r;
		}

		dict.setUpdateUserId(getUserId());
		dict.setUpdateDate(new Date());
		try {
			dictService.doEdit(dict);
		} catch (Exception e) {
			logger.error("数据字典更新失败",e);
		}
		return R.ok();
	}

	/**
	 * 删除
	 */
	@PostMapping("/remove")
	@ResponseBody
	@Log("删除数据字典")
	@RequiresPermissions("base:dict:remove")
	public R remove(Long id) {
		R r = checkChildren(new Long[] {id});
		if (R.ok().equals(r)) {
			try {
				dictService.remove(id);
			} catch (Exception e) {
				logger.error("数据字典删除失败",e);
			}
			return R.ok();
		} else {
			return r;
		}
	}

	/**
	 * 删除
	 */
	@PostMapping("/batchRemove")
	@ResponseBody
	@Log("批量删除数据字典")
	@RequiresPermissions("base:dict:batchRemove")
	public R remove(@RequestParam("ids[]") Long[] ids) {
		R r = checkChildren(ids);
		if (R.ok().equals(r)) {
			try {
				dictService.batchRemove(ids);
			} catch (Exception e) {
				logger.error("数据字典批量删除失败",e);
			}
			return R.ok();
		} else {
			return r;
		}
		
	}

	@GetMapping("/type")
	@ResponseBody
	public List<DictDO> listType() {
		return dictService.listType();
	};

	@ResponseBody
	@GetMapping("/list/{value}")
	public List<DictDO> listByType(@PathVariable("value") String value) {
		// 查询列表数据
		Map<String, Object> map = new HashMap<>(16);
		map.put("value", value);
		List<DictDO> parentList = dictService.list(map);
		
		List<DictDO> dictList = null;
		if (null != parentList && parentList.size() > 0) {
			map = new HashMap<>(16);
			DictDO dictDO = parentList.get(0);
			map.put("parentId",dictDO.getId());
			dictList = dictService.list(map);
		}
		return null == dictList ? new ArrayList<DictDO>() : dictList;
	}

	@GetMapping("/tree")
	@ResponseBody
	public Tree<DictDO> tree() {
		Tree<DictDO> tree = new Tree<DictDO>();
		tree = dictService.getTree();
		return tree;
	}

	/**
	 * 校验编码与值是否存在重复
	 * 
	 * @param vo
	 * @return
	 */
	public R checkValue(DictVO vo) {
		// 查询列表数据
		Map<String, Object> map = new HashMap<>(16);
		map.put("value", vo.getValue());
		List<DictDO> dictList = dictService.list(map);
		if (null != dictList && dictList.size() > 0) {
			for (DictDO dictDO : dictList) {
				if (null != vo.getId() && vo.getId() > 0) {// 修改操作
					if (vo.getType() == Constant.DICT_TYPE_CLASS) {
						// 修改数据分类
						if (vo.getValue().equals(dictDO.getValue()) && vo.getId() != dictDO.getId()) {
							return R.error("编码已存在");
						}
					} else {
						// 修改数据值
						if (vo.getValue().equals(dictDO.getValue()) && vo.getId() != dictDO.getId()
								&& dictDO.getType() == Constant.DICT_TYPE_CLASS) {
							// 值与数据分类的编码重复
							return R.error("编码已存在");
						} else if (vo.getValue().equals(dictDO.getValue()) && vo.getId() != dictDO.getId()
								&& dictDO.getParentId() == vo.getParentId()) {
							// 值与同级数据的值重复
							return R.error("编码已存在");
						}
					}

				} else {
					if (vo.getType() == Constant.DICT_TYPE_CLASS) {
						// 修改数据分类
						if (vo.getValue().equals(dictDO.getValue())) {
							return R.error("编码已存在");
						}
					} else {
						// 修改数据值
						if (vo.getValue().equals(dictDO.getValue()) && dictDO.getType() == Constant.DICT_TYPE_CLASS) {
							// 值与数据分类的编码重复
							return R.error("编码已存在");
						} else if (vo.getValue().equals(dictDO.getValue())
								&& dictDO.getParentId() == vo.getParentId()) {
							// 值与同级数据的值重复
							return R.error("编码已存在");
						}
					}
				}
			}
		}

		return R.ok();
	}
	
	/**
	 * 删除字典时，不能存在子属性
	 * @param ids
	 * @return
	 */
	public R checkChildren(Long[] ids) {
		Map<String, Object> params = new HashMap<String,Object>();
		for (Long id : ids) {
			params.put("parentId",id);
			int total = dictService.count(params);
			if (total > 0) {
				return R.error("所选字典中存在子属性，无法删除");
			}
		}
		return R.ok();
	}
}
